package com.njxxted.activiti.modules.process.identity.service.impl;

import com.njxxted.activiti.modules.process.extend.dao.ActIdentityDao;
import com.njxxted.activiti.modules.process.identity.service.IActIdentityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.stream.Collectors;

/**
 * 描述：流程用户权限 service
 * <p>
 * 作者：Ostrich Hu
 * 时间：2019/9/5 16:28 星期四
 */
@Service
public class IActIdentityServiceImpl implements IActIdentityService {

    private final ActIdentityDao actIdentityDao;

    @Autowired
    public IActIdentityServiceImpl(ActIdentityDao actIdentityDao) {
        this.actIdentityDao = actIdentityDao;
    }

    @Override
    public List<Map<String, Object>> getSelectTree(String groupType) {
        //1查询出所有
        List<Map<String, Object>> originalDeparts = actIdentityDao.getTreeInGroup(groupType);

        //2过滤出所有顶级
        Set<Map<String, Object>> rootDeparts = originalDeparts.parallelStream().
                filter(departDto -> (departDto != null && "0".equals(departDto.get("pId")))).collect(Collectors.toSet());

        List<Map<String, Object>> list = new CopyOnWriteArrayList<>();

        // 为一级菜单设置子，getChild是递归调用的
        rootDeparts.parallelStream().forEach(parentObj -> {
            if (Objects.equals(parentObj.get("pId").toString(), "0")) {
                Map<String, Object> map = new HashMap<>();
                map.put("value", parentObj.get("value"));
                map.put("label", parentObj.get("label"));
                map.put("type", parentObj.get("type"));
                map.put("children", getChildForMap(parentObj.get("value").toString(), originalDeparts));
                list.add(map);
            }
        });

        return list;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public int updateActGroupById(String groupId, String name, String type, String pId) {
        return actIdentityDao.updateActGroupById(groupId, name, type, pId);
    }

    @Override
    public List<Map<String, Object>> getUserByGroupId(String groupId) {
        return actIdentityDao.getUserByGroupId(groupId, null);
    }

    @Override
    public List<Map<String, Object>> getUserByGroupId(String groupId, String conditionSql) {
        return actIdentityDao.getUserByGroupId(groupId, conditionSql);
    }

    @Override
    public List<Map<String, Object>> getSelect(String groupId, String type) {
        return actIdentityDao.getSelect(groupId, type);
    }

    @Override
    public boolean hasChildren(String groupPid, String type) {
        return actIdentityDao.hasChildren(groupPid, type) > 0;
    }

    /**
     * 递归获取子级
     * Map格式
     *
     * @param pId             父id
     * @param originalDeparts 所有菜单
     * @return
     */
    private static Set<Map<String, Object>> getChildForMap(String pId, List<Map<String, Object>> originalDeparts) {

        // 子菜单
        Set<Map<String, Object>> childList = new CopyOnWriteArraySet<>();
        //转换子级
        originalDeparts.parallelStream().forEach(childObj -> {
            // 遍历所有节点，将父id与传过来的id比较
            if (!Objects.equals(childObj.get("pId").toString(), "0")
                    && Objects.equals(pId, childObj.get("pId").toString())) {
                Map<String, Object> map = new HashMap<>();
                map.put("value", childObj.get("value"));
                map.put("pId",childObj.get("pId"));
                map.put("label", childObj.get("label").toString());
                map.put("type", childObj.get("type"));
                childList.add(map);
            }
        });

        // 把子菜单的子菜单再循环一遍
        childList.parallelStream().forEach(child -> {
            //递归
            child.put("children", getChildForMap(child.get("value").toString(), originalDeparts));
        });
        return childList.size() > 0 ? childList : null;
    }
}
